package com.smile.service.job;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.smile.commons.file.FileUtils;
import com.smile.file.uitl.MinioUtil;
import com.smile.mapper.*;
import com.smile.model.domain.*;
import com.smile.service.entity.drc.HeartBeatData;
//import com.xxl.job.core.context.XxlJobHelper;
//import com.xxl.job.core.handler.annotation.XxlJob;
import com.smile.service.service.MqttMessageSender;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.info.ProjectInfoProperties;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;


import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

import org.springframework.web.multipart.MultipartFile;
import ws.schild.jave.*;
import java.net.*;
import java.math.*;


@Component
public class DeviceJob {

    // 缩略图存储目录
    private static final String THUMBNAIL_DIR = "/app/thumbnails";

    @Autowired
    private MqttMessageSender mqttMessageSender;

    @Autowired
    private AirportInfoMapper airportInfoMapper;

    @Autowired
    private FlightStatisticsMapper flightStatisticsMapper;

    @Autowired
    private FlightTaskMapper flightTaskMapper;



    @Autowired
    private InspectionTaskMapper inspectionTaskMapper;

    @Autowired
    private MediaMapper mediaMapper;
    @Autowired
    private DroneMapper droneMapper;
    @Autowired
    private ProjectInfoProperties projectInfoProperties;

    /**
     * 40秒定时统计
     */
    @Scheduled(fixedRate = 40000)
    public void statistics() {
        System.out.println("执行统计");
        QueryWrapper<FeisuanFlightTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", "4");
        queryWrapper.isNotNull("airport_id");
        queryWrapper.isNotNull("end_time");
        queryWrapper.eq("is_statistics",0);
        List<FeisuanFlightTask> feisuanFlightTasks = flightTaskMapper.selectList(queryWrapper);

        if (feisuanFlightTasks != null && feisuanFlightTasks.size() > 0) {
            for (FeisuanFlightTask flightTask : feisuanFlightTasks) {
                QueryWrapper<FeisuanFlightStatistics> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.eq("statistics_date", flightTask.getCreateTime().toLocalDate());
                queryWrapper1.eq("airport_id",flightTask.getAirportId());
                queryWrapper1.eq("drone_id",flightTask.getDroneId());
                queryWrapper1.eq("organization_id",flightTask.getOrganizationId());
                queryWrapper1.last("limit 1");
                FeisuanFlightStatistics statistics = flightStatisticsMapper.selectOne(queryWrapper1);
                if (statistics != null) {
                    statistics.setTaskCount(statistics.getTaskCount() + 1);
                    statistics.setTotalTaskTime(statistics.getTotalTaskTime() + flightTask.getFlightTime());
                    statistics.setTotalTaskDistance(statistics.getTotalTaskDistance() + flightTask.getFlightDistance());
                    flightStatisticsMapper.updateById(statistics);
                }else{
                    FeisuanFlightStatistics  statistics1 = new FeisuanFlightStatistics();
                    statistics1.setTaskCount(1);
                    statistics1.setTotalTaskTime(flightTask.getFlightTime());
                    statistics1.setTotalTaskDistance(flightTask.getFlightDistance());
                    statistics1.setDroneId(flightTask.getDroneId());
                    statistics1.setOrganizationId(flightTask.getOrganizationId());
                    statistics1.setAirportId(flightTask.getAirportId());
                    statistics1.setStatisticsDate(flightTask.getCreateTime().toLocalDate());
                    flightStatisticsMapper.insert(statistics1);
                }
                flightTask.setIsStatistics(1);
                flightTaskMapper.updateById(flightTask);
            }
        }
    }

    @Scheduled(fixedRate = 2000)
    public void heartbeat() {
        JSONObject jsonObject = new JSONObject();
        HeartBeatData heartBeatData = new HeartBeatData();
        heartBeatData.setTimestamp(System.currentTimeMillis());
        jsonObject.put("method", "heart_beat");
        System.out.println(jsonObject.toJSONString());

        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(date);
        System.out.println(formattedDate);
        jsonObject.put("data", heartBeatData);
        try {
            this.process(jsonObject.toJSONString());
        } catch (MqttException e) {
            System.out.println(e.getMessage());
            throw new RuntimeException(e);
        }
    }

    public Boolean process(String data) throws MqttException {
//        MqttMessage message = new MqttMessage();
//        message.setQos(0);
//        message.setRetained(true);
//        message.setPayload(data.getBytes());
        //获取所有在线的机场
        QueryWrapper<FeisuanAirportInfo> queryWrapper = new QueryWrapper<>();
        long timestamp = System.currentTimeMillis()-5000;
        Date date = new Date(timestamp);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(date);
        queryWrapper.gt("modify_time", formattedDate);
        //维护在线的心跳
        List<FeisuanAirportInfo> list = airportInfoMapper.selectList(queryWrapper);
        for (FeisuanAirportInfo feisuanAirportInfo : list) {
            mqttMessageSender.sendMsg("thing/product/" + feisuanAirportInfo.getGatewaySn() + "/services", data);
            mqttMessageSender.sendMsg("thing/product/" + feisuanAirportInfo.getGatewaySn() + "/drc/down", data);
        }
        return Boolean.TRUE;
    }


    /**
     * 定时统计设备的飞行数据
     */
    @Scheduled(fixedRate = 40000)
    public void statisticsDrone() {
        System.out.println("更新无人机统计数据");
        QueryWrapper<FeisuanDrone> queryWrapper = new  QueryWrapper<>();
        List<FeisuanDrone> feisuanDrones = droneMapper.selectList(queryWrapper);
        for (FeisuanDrone feisuanDrone : feisuanDrones) {
            CountFlight  countFlight = flightStatisticsMapper.countFlight(feisuanDrone.getId());
            if (countFlight != null) {
                UpdateWrapper<FeisuanDrone> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("id", feisuanDrone.getId());
                updateWrapper.set("total_task_distance", countFlight.getDistance());
                updateWrapper.set("total_task_time", countFlight.getTime());
                updateWrapper.set("task_count", countFlight.getNum());
                droneMapper.update(new FeisuanDrone(), updateWrapper);
            }
        }
    }


    /**
     * 定时统计设备的飞行数据
     */
    @Scheduled(fixedRate = 40000)
    public void updateAirlineTaskStatus() {
        System.out.println("定时更新未处理数据");
        QueryWrapper<FeisuanInspectionTask> queryWrapper = new  QueryWrapper<>();
        queryWrapper.eq("status", "1");
        List<FeisuanInspectionTask> feisuanInspectionTasks = inspectionTaskMapper.selectList(queryWrapper);
        for (FeisuanInspectionTask i : feisuanInspectionTasks) {
            if(i.getStatus() == 1){
                if (Objects.isNull(i.getPlanStartTime())){
                    i.setStatus(5);
                    i.setErrorCode(1);
                    i.setErrorMessage("超时未执行");
                    inspectionTaskMapper.updateById(i);
                }else{
                    Duration duration = Duration.between(i.getPlanStartTime(), LocalDateTime.now());

                    if(duration.getSeconds() > 100){
                        i.setStatus(5);
//                        i.setErrorCode(1);
                        i.setErrorMessage("超时未执行");
                        inspectionTaskMapper.updateById(i);
                    }
                }

            }
        }
    }


    /**
     * 定时统计图片数据
     */
    @Scheduled(fixedRate = 40000)
    public void updateMedia() {
        System.out.println("定时处理文件");
        QueryWrapper<FeisuanMedia> queryWrapper = new  QueryWrapper<>();
        queryWrapper.eq("is_update", 0);
        queryWrapper.eq("file_type", 2);
        queryWrapper.eq("suffix", "jpeg");
        List<FeisuanMedia> feisuanMediaList = mediaMapper.selectList(queryWrapper);
        for (FeisuanMedia i : feisuanMediaList) {
            if (i.getSuffix().equals("jpeg")){

                try {
                    URL url = new URL(i.getFileUrl());
                    System.out.println(i.getFileUrl());
                    try (InputStream in = url.openStream()) {
                        BufferedImage image = ImageIO.read(in);
                        int width = image.getWidth();
                        int height = image.getHeight();
                        long fileSize = in.available(); // 不准确已废弃
                        HttpURLConnection conn = (HttpURLConnection) new URL(i.getFileUrl()).openConnection();
                        conn.setRequestMethod("HEAD");
                        System.out.println("文件大小: " + conn.getHeaderField("Content-Length") + " bytes");

                        i.setFileSize( Long.valueOf( conn.getHeaderField("Content-Length")));
                        i.setResolution(width+"x"+height);
                        i.setIsUpdate(1);
                        mediaMapper.updateById(i);
                    } catch (IOException e) {
                        System.out.println(e.getMessage());
                    }
                }catch (Exception e){

                }
            }
        }
    }

    /**
     * 定时统计图片数据
     */
    @Scheduled(fixedRate = 40000)
    public void updateVideo() {
        System.out.println("定时处理视频");
        QueryWrapper<FeisuanMedia> queryWrapper = new  QueryWrapper<>();
        queryWrapper.eq("is_update", 0);
        queryWrapper.eq("file_type", 2);
        queryWrapper.eq("suffix", "mp4");

        List<FeisuanMedia> feisuanMediaList = mediaMapper.selectList(queryWrapper);
        for (FeisuanMedia i : feisuanMediaList) {
            if (i.getSuffix().equals("mp4")){

                try {
                    // 获取文件大小
                    URLConnection conn = new URL(i.getFileUrl()).openConnection();
                    System.out.println("文件大小: " + conn.getContentLengthLong() + " bytes");

                    // 获取视频参数
                    MultimediaObject media = new MultimediaObject(new URL(i.getFileUrl()));
                    MultimediaInfo info = media.getInfo();

                    System.out.println("时长(秒): " + info.getDuration()/1000);
                    VideoInfo video = info.getVideo();
                    System.out.println("分辨率: " + video.getSize().getWidth() + "x" + video.getSize().getHeight());
                    System.out.println("帧率: " + video.getFrameRate());
                    System.out.println("码率: " + video.getBitRate() + " bps");
                    System.out.println("码率: " + video.getBitRate() + " bps");

                    i.setFileSize( conn.getContentLengthLong());
                    i.setResolution(video.getSize().getWidth()+"x"+video.getSize().getHeight());
                    i.setDuration(info.getDuration()/1000);
                    i.setFrameRate( Long.valueOf((long) video.getFrameRate()));
                    i.setIsUpdate(1);
                    mediaMapper.updateById(i);

                } catch (Exception e) {
                    e.printStackTrace();
                }

                try {
                    URL url = new URL(i.getFileUrl());
                    System.out.println(i.getFileUrl());
                    try (InputStream in = url.openStream()) {
                        BufferedImage image = ImageIO.read(in);
                        int width = image.getWidth();
                        int height = image.getHeight();
                        long fileSize = in.available(); // 注意：在某些情况下，这个方法可能不准确或不可用

                    } catch (IOException e) {
                        System.out.println(e.getMessage());
                    }
                }catch (Exception e){

                }
            }
        }
    }

    /**
     * 从视频中截取第一帧画面作为缩略图
     * @param videoUrl 视频文件URL
     * @param thumbnailPath 缩略图保存路径
     * @return 是否成功截取
     */
    public boolean extractVideoThumbnail(String videoUrl, String thumbnailPath) {
        try {
            System.out.println("开始截取视频缩略图: " + videoUrl);

            // 确保目录存在
            Path path = Paths.get(thumbnailPath);
            Files.createDirectories(path.getParent());

            // 构建FFmpeg命令
            String ffmpegCommand = String.format(
                    "ffmpeg -i \"%s\" -ss 00:00:01 -vframes 1 -q:v 2 \"%s\"",
                    videoUrl, thumbnailPath
            );

            System.out.println("执行FFmpeg命令: " + ffmpegCommand);

            // 执行FFmpeg命令
            Process process = Runtime.getRuntime().exec(ffmpegCommand);

            // 读取命令输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println("FFmpeg输出: " + line);
            }

            while ((line = errorReader.readLine()) != null) {
                System.out.println("FFmpeg错误: " + line);
            }

            // 等待命令执行完成
            int exitCode = process.waitFor();

            // 检查文件是否生成成功
            File thumbnailFile = new File(thumbnailPath);
            if (exitCode == 0 && thumbnailFile.exists() && thumbnailFile.length() > 0) {
                System.out.println("缩略图保存成功: " + thumbnailPath);
                System.out.println("缩略图文件大小: " + thumbnailFile.length() + " bytes");
                return true;
            } else {
                System.out.println("截取帧失败，退出码: " + exitCode);
                return false;
            }

        } catch (Exception e) {
            System.err.println("截取视频缩略图失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 定时处理视频缩略图生成
     */
    @Scheduled(fixedRate = 60000) // 每分钟执行一次
    public void generateVideoThumbnails() {
        System.out.println("开始定时生成视频缩略图");

        try {
            // 查询未生成缩略图的视频文件，每次处理10个
            QueryWrapper<FeisuanMedia> queryWrapper = new QueryWrapper<>();
            // 文件类型file_type = 2 表示视频文件和图片 1 文件夹 2 图片 2 视频
            queryWrapper.eq("file_type", 2)
                    .eq("thumbnail_generated", 0) // 未生成缩略图
                    .eq("delete_status", 0) // 未删除
                    .isNotNull("file_url") // 文件URL不为空
                    .last("LIMIT 10"); // 限制每次处理10个

            List<FeisuanMedia> videoFiles = mediaMapper.selectList(queryWrapper);

            if (videoFiles.isEmpty()) {
                System.out.println("没有需要生成缩略图的视频文件");
                return;
            }

            System.out.println("开始处理 " + videoFiles.size() + " 个视频文件的缩略图生成");

            for (FeisuanMedia media : videoFiles) {
                try {
                    String videoUrl = media.getFileUrl();
                    if (videoUrl == null || videoUrl.trim().isEmpty()) {
                        System.out.println("跳过无效的视频URL: " + media.getId());
                        continue;
                    }

                    // 生成缩略图文件名
                    String fileName = media.getFileName();
                    if (fileName == null || fileName.isEmpty()) {
                        fileName = "video_" + media.getId();
                    }
                    String thumbnailFileName = fileName.replaceAll("\\.[^.]*$", "_thumb.jpg");
                    String thumbnailPath = THUMBNAIL_DIR + File.separator + thumbnailFileName;

                    // 生成缩略图
                    boolean success = extractVideoThumbnail(videoUrl, thumbnailPath);

                    String url = "";
                    try {
                        // 1. 定义缩略图本地路径
                        File file = new File(thumbnailPath);
                        if (!file.exists()) {
                            throw new FileNotFoundException("缩略图文件不存在: " + thumbnailPath);
                        }
                        // 2. File -> MultipartFile
                        MultipartFile multipartFile = FileUtils.fileToMultipartFile(file, file.getName());
                        // 3. 初始化 Minio 工具类
                        MinioUtil minioUtil = new MinioUtil();
                        // 4. 上传到 Minio的 my-bucket 存在 device-thumbnail 文件夹下
                        Map<String, Object> fileInfo = minioUtil.uploadFile(multipartFile, "my-bucket" , "device-thumbnail");
                        // 5. 获取 URL上传到 minio 之后的视频第一帧图片的相对路径
                        url = (String)fileInfo.get("url");

                    } catch(IOException e) {
                        System.out.println("生成缩略图失败: " + e.getMessage());
                    }

                    if (success) {
                        // 更新数据库记录
                        UpdateWrapper<FeisuanMedia> updateWrapper = new UpdateWrapper<>();
                        updateWrapper.eq("id", media.getId())
                                .set("thumbnail_url", url)
                                .set("thumbnail_generated", 1)
//                                .set("thumbnail_generate_time", LocalDateTime.now())
                                .set("thumbnail_size", new File(thumbnailPath).length());

                        mediaMapper.update(null, updateWrapper);

                        System.out.println("成功生成缩略图: " + media.getFileUrl() + " -> " + thumbnailPath);
                    } else {
                        System.out.println("生成缩略图失败: " + media.getFileUrl());
                    }

                } catch (Exception e) {
                    System.err.println("处理视频文件缩略图时出错: " + media.getFileUrl() + ", 错误: " + e.getMessage());
                    e.printStackTrace();
                }
            }

        } catch (Exception e) {
            System.err.println("定时生成视频缩略图任务执行出错: " + e.getMessage());
            e.printStackTrace();
        }

        System.out.println("视频缩略图生成任务完成");
    }

}
